home *** CD-ROM | disk | FTP | other *** search
-
- /*© copyright 1991-96 UserLand Software, Inc. All Rights Reserved.*/
-
-
- /*
- Briefly -- this is a very small program that demonstrates the UserLand Outline Sharing
- protocol. For detailed info, see the enclosed "About Outline Sharing" file.
-
- Please contact UserLand Software at on AppleLink at the UserLand Discussion board under
- the Third Parties icon, or GO USERLAND on CompuServe for further information on outline
- sharing.
-
- We hope you like outline sharing and add it to your Macintosh application.
-
- Thanks!
-
- UserLand Software
-
- 7/1/92 DW: Added support for system event handlers.
- */
-
-
- #include <menusharing.h>
- #include <iac.h>
- #include "outlinesharing.h"
-
-
- #define applemenu 128 /*the resource id of the apple menu*/
-
- #define aboutitem 1 /*the about command*/
-
- #define filemenu 129 /*resource id of file menu, shared menus appear to right of this*/
-
- #define firstsharedmenu filemenu+1 /*resource id for first shared menu*/
-
- #define quititem 1 /*the single item in the file menu -- this is a very simple program!*/
-
- MenuHandle happlemenu, hfilemenu; /*the two fixed, non-shared menus in this program*/
-
- WindowPtr mainwindow = nil; /*the menu sharing test window*/
-
- Str255 windowmessage; /*the message that's displayed in the main window*/
-
- short flexitmainloop = false; /*when true we fall thru the main event loop*/
-
-
-
-
- static void copystring (Str255 source, Str255 dest) {
-
- /*
- create a copy of source in dest. copy the length byte and
- all the characters in the source string.
-
- assume the strings are pascal strings, with the length byte in
- the first character of the string.
- */
-
- register short i, len;
-
- len = (short) source [0];
-
- for (i = 0; i <= len; i++)
- dest [i] = source [i];
- } /*copystring*/
-
-
- static void ellipsize (Str255 s, short width) {
-
- /*
- if the string fits inside the given number of pixels, fine -- do nothing
- and return.
-
- if not, return a string that does fit, with ellipses representing the
- deleted characters. ellipses are generated by pressing option-semicolon.
- */
-
- register char len;
- register short newwidth;
-
- if ((newwidth = StringWidth (s)) <= width) /*nothing to do, the string fits*/
- return;
-
- len = s [0]; /* current length in characters*/
-
- width -= CharWidth ('…'); /* subtract width of ellipses*/
-
- do { /*until it fits (or we run out of characters)*/
-
- newwidth -= CharWidth (s [len]);
-
- --len;
- } while ((newwidth > width) && (len != 0));
-
- ++len; /*make room for the ellipses*/
-
- s [len] = '…';
-
- s [0] = (char) len;
- } /*ellipsize*/
-
-
- static void centerstring (Rect r, Str255 s) {
-
- /*
- draw the string in the current font, size and style, centered inside
- the indicated rectangle.
- */
-
- register short rh = r.bottom - r.top;
- register short rw = r.right - r.left;
- register short h, v;
- FontInfo fi;
-
- GetFontInfo (&fi);
-
- ellipsize (s, rw); /*make sure it fits inside the rectangle, width-wise*/
-
- h = r.left + ((rw - StringWidth (s)) / 2);
-
- v = r.top + ((rh - (fi.ascent + fi.descent)) / 2) + fi.ascent;
-
- MoveTo (h, v);
-
- ClipRect (&r);
-
- DrawString (s);
- } /*centerstring*/
-
-
- static void setfontsizestyle (short fontnum, short fontsize, short fontstyle) {
-
- TextFont (fontnum);
-
- TextSize (fontsize);
-
- TextFace (fontstyle);
- } /*setfontsizestyle*/
-
-
- static void updatemainwindow (void) {
-
- Rect r;
- Str255 s;
-
- r = (*mainwindow).portRect;
-
- EraseRect (&r);
-
- setfontsizestyle (helvetica, 12, 0);
-
- centerstring (r, windowmessage);
-
- NumToString (FreeMem () / 1024, s);
-
- MoveTo (r.left + 3, r.bottom - 3);
-
- setfontsizestyle (geneva, 9, 0);
-
- DrawString (s);
-
- DrawString ("\pK");
- } /*updatemainwindow*/
-
-
- static Boolean setwindowmessage (Str255 s) {
-
- copystring (s, windowmessage);
-
- SetPort (mainwindow);
-
- updatemainwindow ();
-
- return (true);
- } /*setwindowmessage*/
-
-
- static Boolean initmainwindow (void) {
-
- register WindowPtr w;
-
- w = mainwindow = GetNewWindow (128, nil, (WindowPtr) -1);
-
- if (w == nil)
- return (false);
-
- ShowWindow (w);
-
- return (true);
- } /*initmainwindow*/
-
-
- static void handleupdate (EventRecord *ev) {
-
- register WindowPtr w;
-
- w = (WindowPtr) (*ev).message;
-
- BeginUpdate (w);
-
- SetPort (w);
-
- updatemainwindow ();
-
- EndUpdate (w);
- } /*handleupdate*/
-
-
- static void handledrag (EventRecord *ev, WindowPtr w) {
-
- Rect r;
-
- r = qd.screenBits.bounds;
-
- r.top = r.top + GetMBarHeight ();
-
- InsetRect (&r, 4, 4);
-
- DragWindow (w, (*ev).where, &r);
- } /*handledrag*/
-
-
- static void handlemenu (long codeword) {
-
- register short idmenu, iditem;
-
- iditem = LoWord (codeword);
-
- idmenu = HiWord (codeword);
-
- if (SharedMenuHit (idmenu, iditem))
- goto exit;
-
- switch (idmenu) {
-
- case applemenu:
- switch (iditem) {
-
- case aboutitem:
- Alert (262, nil);
-
- break;
-
- default: {
-
- Str255 s;
-
- GetItem (happlemenu, iditem, s);
-
- OpenDeskAcc (s);
-
- break;
- }
- } /*switch*/
-
- break; /*apple menu*/
-
- case filemenu:
- switch (iditem) {
-
- case quititem:
-
- flexitmainloop = true;
-
- break;
- } /*switch*/
-
- break; /*file menu*/
-
- } /*switching on which menu was invoked*/
-
- exit:
-
- HiliteMenu (0);
- } /*handlemenu*/
-
-
- static void handlemouse (EventRecord *ev) {
-
- register short part;
- WindowPtr w;
-
- part = FindWindow ((*ev).where, &w);
-
- if (w != nil)
-
- if (w != FrontWindow ()) { /*just like all other Mac programs*/
-
- SelectWindow (w);
-
- return; /*the mouse click is consumed by the bringtofront operation*/
- }
-
- switch (part) {
-
- case inMenuBar:
- handlemenu (MenuSelect ((*ev).where));
-
- break;
-
- case inSysWindow:
- SystemClick (ev, w);
-
- break;
-
- case inDrag:
- handledrag (ev, w);
-
- break;
-
- } /*switch*/
- } /*handlemouse*/
-
-
- static void handlekeystroke (EventRecord *ev) {
-
- register char ch = (*ev).message & charCodeMask;
-
- if (SharedScriptRunning ()) { /*cmd-period terminates the script*/
-
- if (((*ev).modifiers & cmdKey) && (ch == '.')) {
-
- CancelSharedScript (); /*cancel the shared menu script, if one is running*/
-
- return;
- }
- }
-
- handlemenu (MenuKey (ch)); /*not cmd-period, process the normal way*/
- } /*handlekeystroke*/
-
-
- static void handleevent (EventRecord *ev) {
-
- switch ((*ev).what) {
-
- case keyDown: case autoKey:
- handlekeystroke (ev);
-
- break;
-
- case mouseDown:
- handlemouse (ev);
-
- break;
-
- case updateEvt:
- handleupdate (ev);
-
- break;
-
- case kHighLevelEvent:
- AEProcessAppleEvent (ev);
-
- break;
- } /*switch*/
- } /*handleevent*/
-
-
- static void maineventloop (void) {
-
- EventRecord ev;
-
- while (!flexitmainloop) {
-
- if (WaitNextEvent (everyEvent, &ev, 1, nil))
- handleevent (&ev);
-
- CheckSharedMenus (firstsharedmenu);
- } /*while*/
- } /*maineventloop*/
-
-
- static void initmenus (void) {
-
- /*
- set up our apple and file menus. nothing fancy.
- */
-
- happlemenu = GetMenu (applemenu);
-
- AddResMenu (happlemenu, 'DRVR');
-
- InsertMenu (happlemenu, 0);
-
- hfilemenu = GetMenu (filemenu);
-
- InsertMenu (hfilemenu, 0);
-
- DrawMenuBar ();
- } /*initmenus*/
-
-
- static void initmacintosh (void) {
-
- /*
- the magic stuff that every Macintosh application needs to do
- before doing anything else.
- */
-
- register short i;
-
- MaxApplZone ();
-
- for (i = 0; i < 10; i++)
- MoreMasters ();
-
- InitGraf (&qd.thePort);
-
- InitFonts ();
-
- FlushEvents (everyEvent, 0);
-
- InitWindows ();
-
- InitMenus ();
-
- TEInit ();
-
- InitDialogs (0L);
-
- InitCursor ();
-
- for (i = 0; i < 5; i++) { /*register with Multifinder*/
-
- EventRecord ev;
-
- EventAvail (everyEvent, &ev); /*see TN180 -- splash screen*/
- } /*for*/
- } /*initmacintosh*/
-
-
- static pascal OSErr handlequit (AppleEvent *event, AppleEvent *reply, long refcon) {
-
- /*DebugStr ("\pquitapp");*/
-
- flexitmainloop = true;
-
- return (noErr);
- } /*handlequit*/
-
-
- static pascal OSErr handleopenapp (AppleEvent *event, AppleEvent *reply, long refcon) {
-
- /*DebugStr ("\popenapp");*/
-
- return (noErr);
- } /*handleopenapp*/
-
-
- static pascal Boolean openfilespec (FSSpec *fs) {
-
- /*DebugStr ((*fs).name);*/
-
- return (true);
- } /*openfilespec*/
-
-
- static pascal Boolean printfilespec (FSSpec *fs) {
-
- /*DebugStr ((*fs).name);*/
-
- return (true);
- } /*printfilespec*/
-
-
- static pascal OSErr handleopen (AppleEvent *event, AppleEvent *reply, long refcon) {
-
- IACglobals.event = event;
-
- IACglobals.reply = reply;
-
- IACglobals.refcon = refcon;
-
- return (IACdrivefilelist (&openfilespec));
- } /*handleopen*/
-
-
- static pascal OSErr handleprint (AppleEvent *event, AppleEvent *reply, long refcon) {
-
- IACglobals.event = event;
-
- IACglobals.reply = reply;
-
- IACglobals.refcon = refcon;
-
- return (IACdrivefilelist (&printfilespec));
- } /*handleprint*/
-
-
- static pascal OSErr setmessageverb (AppleEvent *event, AppleEvent *reply, long refcon) {
-
- /*
- display a message in OutlineSharer's window.
- */
-
- Str255 s;
-
- if (SharedScriptCancelled (event, reply))
- return (noErr);
-
- IACglobals.event = event;
-
- IACglobals.reply = reply;
-
- if (!IACgetstringparam ((OSType) keyDirectObject, s))
- return (noErr);
-
- IACreturnboolean (setwindowmessage (s));
-
- return (noErr);
- } /*setmessageverb*/
-
-
- static pascal OSErr setoutlineverb (AppleEvent *event, AppleEvent *reply, long refcon) {
-
- /*
- set the current outline from the outline parameter passed as part
- of the Apple Event.
- */
-
- hdloutlinerecord houtline;
-
- if (SharedScriptCancelled (event, reply))
- return (noErr);
-
- IACglobals.event = event;
-
- IACglobals.reply = reply;
-
- if (!IACgetoutlineparam ((OSType) keyDirectObject, &houtline))
- return (noErr);
-
- opDisposeOutlineRecord (outlinedata); /*only one outline managed at a time*/
-
- outlinedata = houtline; /*set the current outline*/
-
- IACreturnboolean (true);
-
- return (noErr);
- } /*setoutlineverb*/
-
-
- static Boolean nooutlineerror (void) {
-
- if (outlinedata == nil) {
-
- IACreturnerror (1, "\pNo outline has been sent to OutlineSharer");
-
- return (true);
- }
-
- return (false);
- } /*nooutlineerror*/
-
-
- static pascal OSErr getoutlineverb (AppleEvent *event, AppleEvent *reply, long refcon) {
-
- /*
- return the outline that's resident in OutlineSharer.
- */
-
- if (SharedScriptCancelled (event, reply))
- return (noErr);
-
- IACglobals.event = event;
-
- IACglobals.reply = reply;
-
- if (nooutlineerror ())
- return (noErr);
-
- IACreturnoutline (outlinedata);
-
- return (noErr);
- } /*getoutlineverb*/
-
-
- static void allupper (Str255 bs) {
-
- register char len = bs [0];
- register char *p = (char *) &bs [1];
- register char ch;
-
- while (len--) {
-
- ch = *p;
-
- if ((ch >= 'a') && (ch <= 'z'))
- *p -= 32;
-
- p++;
- } /*while*/
- } /*allupper*/
-
-
- static Boolean uppercasevisit (hdlheadrecord hnode) {
-
- Str255 bs;
-
- opGetHeadString (hnode, bs);
-
- allupper (bs);
-
- opSetHeadString (hnode, bs);
-
- return (true);
- } /*uppercasevisit*/
-
-
- static pascal OSErr uppercaseoutlineverb (AppleEvent *event, AppleEvent *reply, long refcon) {
-
- /*
- convert all the characters in the current outline to lowercase.
- */
-
- if (SharedScriptCancelled (event, reply)) /*part of the menu sharing protocol*/
- return (noErr);
-
- IACglobals.event = event;
-
- IACglobals.reply = reply;
-
- if (nooutlineerror ()) /*no outline to uppercase*/
- return (noErr);
-
- opVisitOutline (uppercasevisit); /*visit every node in the outline*/
-
- IACreturnboolean (true);
-
- return (noErr);
- } /*uppercaseoutlineverb*/
-
-
- static void alllower (Str255 bs) {
-
- register char len = bs [0];
- register char *p = (char *) &bs [1];
- register char ch;
-
- while (len--) {
-
- ch = *p;
-
- if ((ch >= 'A') && (ch <= 'Z'))
- *p += 32;
-
- p++;
- } /*while*/
- } /*alllower*/
-
-
- static Boolean lowercasevisit (hdlheadrecord hnode) {
-
- Str255 bs;
-
- opGetHeadString (hnode, bs);
-
- alllower (bs);
-
- opSetHeadString (hnode, bs);
-
- return (true);
- } /*lowercasevisit*/
-
-
- static pascal OSErr lowercaseoutlineverb (AppleEvent *event, AppleEvent *reply, long refcon) {
-
- /*
- convert all the characters in the current outline to lowercase.
- */
-
- if (SharedScriptCancelled (event, reply)) /*part of the menu sharing protocol*/
- return (noErr);
-
- IACglobals.event = event;
-
- IACglobals.reply = reply;
-
- if (nooutlineerror ()) /*no outline to lowercase*/
- return (noErr);
-
- opVisitOutline (lowercasevisit); /*visit every node in the outline*/
-
- IACreturnboolean (true);
-
- return (noErr);
- } /*lowercaseoutlineverb*/
-
-
- static pascal void errordialog (Str255 s) {
-
- ParamText (s, "\p", "\p", "\p");
-
- Alert (263, nil);
- } /*errordialog*/
-
-
- static pascal void eventfilter (EventRecord *ev) {
-
- handleevent (ev);
- } /*eventfilter*/
-
-
- void main (void) {
-
- initmacintosh ();
-
- if (!InitSharedMenus (&errordialog, &eventfilter))
- goto error;
-
- if (!IACinstallhandler ('OUTS', 'smsg', (ProcPtr) setmessageverb))
- goto error;
-
- if (!IACinstallsystemhandler ('outs', 'sout', (ProcPtr) setoutlineverb))
- goto error;
-
- if (!IACinstallsystemhandler ('outs', 'gout', (ProcPtr) getoutlineverb))
- goto error;
-
- if (!IACinstallsystemhandler ('outs', 'lcas', (ProcPtr) lowercaseoutlineverb))
- goto error;
-
- if (!IACinstallsystemhandler ('outs', 'ucas', (ProcPtr) uppercaseoutlineverb))
- goto error;
-
- if (!IACinstallhandler (kCoreEventClass, kAEOpenApplication, (ProcPtr) &handleopenapp))
- goto error;
-
- if (!IACinstallhandler (kCoreEventClass, kAEOpenDocuments, (ProcPtr) &handleopen))
- goto error;
-
- if (!IACinstallhandler (kCoreEventClass, kAEPrintDocuments, (ProcPtr) &handleprint))
- goto error;
-
- if (!IACinstallhandler (kCoreEventClass, kAEQuitApplication, (ProcPtr) &handlequit))
- goto error;
-
- initmenus ();
-
- initmainwindow ();
-
- maineventloop ();
-
- ExitToShell ();
-
- error:
-
- Alert (261, nil); /*this application requires system 7.0 or higher*/
-
- ExitToShell ();
- } /*main*/
-
-
-